<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    
    <title>宏任务和微任务 | liuz2&#39;s Blog</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1">
    <meta name="generator" content="Hugo 0.63.1" />
    
    
      <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
    

    
    
      <link href="/dist/css/app.9576afd3b3c158d98f48ec5df01fec6a.css" rel="stylesheet">
    

    

    
      

    

    

    <meta property="og:title" content="宏任务和微任务" />
<meta property="og:description" content="简单认识宏任务和微任务，了解事件循环的基本流程" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://liuz2.gitee.io/posts/task-and-microtask/" />
<meta property="article:published_time" content="2021-10-15T14:31:20+08:00" />
<meta property="article:modified_time" content="2021-10-15T14:31:20+08:00" />
<meta itemprop="name" content="宏任务和微任务">
<meta itemprop="description" content="简单认识宏任务和微任务，了解事件循环的基本流程">
<meta itemprop="datePublished" content="2021-10-15T14:31:20&#43;08:00" />
<meta itemprop="dateModified" content="2021-10-15T14:31:20&#43;08:00" />
<meta itemprop="wordCount" content="151">



<meta itemprop="keywords" content="javascript," /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="宏任务和微任务"/>
<meta name="twitter:description" content="简单认识宏任务和微任务，了解事件循环的基本流程"/>

	
  </head>

  <body class="ma0 avenir bg-white">

    
   
  

  <header>
    <div class="bg-black">
      <nav class="pv3 ph3 ph4-ns" role="navigation">
  <div class="flex-l justify-between items-center center">
    <a href="/" class="f3 fw2 hover-white no-underline white-90 dib">
      
        liuz2&#39;s Blog
      
    </a>
    <div class="flex-l items-center">
      

      
        <ul class="pl0 mr3">
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/about/" title="About page">
              About
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/links/" title="Links page">
              Links
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/timeline/" title="Timeline page">
              Timeline
            </a>
          </li>
          
        </ul>
      
      















    </div>
  </div>
</nav>

    </div>
  </header>



    <main class="pb7" role="main">
      
  
  <article class="flex-l flex-wrap justify-between mw8 center ph3">
    <header class="mt4 w-100">
      <h1 class="f3 athelas mt3 mb1">宏任务和微任务</h1>
      
      
      <time class="f6 mv1 dib tracked" datetime="2021-10-15T14:31:20&#43;08:00">October 15, 2021</time>

      
      
    </header>
    <div class="nested-copy-line-height lh-copy sans-serif f5 nested-links nested-img mid-gray pr4-l w-two-thirds-l"><p>首先查看以下代码，判断代码的输出顺序：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#a6e22e">async</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">async1</span>() {
    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;async1 start&#39;</span>);
    <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">async2</span>();
    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;async1 end&#39;</span>);
}

<span style="color:#a6e22e">async</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">async2</span>() {
    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;async2&#39;</span>);
}

<span style="color:#a6e22e">async1</span>();

<span style="color:#a6e22e">setTimeout</span>(() =&gt; {
    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;timeout&#39;</span>);
}, <span style="color:#ae81ff">0</span>);

<span style="color:#66d9ef">new</span> Promise(<span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">resolve</span>) {
    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;promise1&#39;</span>);
    <span style="color:#a6e22e">resolve</span>();
}).<span style="color:#a6e22e">then</span>(<span style="color:#66d9ef">function</span> () {
    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;promise2&#39;</span>);
});

<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;script end&#39;</span>);
</code></pre></div><p>正确答案是：</p>
<pre><code>async1 start
async2
promise1
script end
async1 end
promise2
timeout
</code></pre><h2 id="事件循环">事件循环</h2>
<p>JavaScript 是单线程语言，只有一个主线程，一次只能做一件事。为了协调用户输入、异步 xhr 返回，脚本代码执行，JavaScript 引入了事件循环（<em>Event Loop</em>）的概念。</p>
<p>每一个事件循环，称为一个 <em>tick</em>。每次 <em>tick</em> 的关键任务是：</p>
<ol>
<li>执行同步任务</li>
<li>检查是否存在微任务，如果有则不断执行，直至清空微任务队列（<em>Microtask Queue</em>）</li>
<li>渲染页面（<em>render</em>）</li>
<li>进入下一次 <em>tick</em></li>
</ol>
<h2 id="宏任务">宏任务</h2>
<p>宏任务（<em>macrotask</em> 或 <em>task</em>），是每次执行栈执行的代码。浏览器为了保持交互灵敏度，会在两次宏任务之间渲染页面。</p>
<p>常见的宏任务包括：</p>
<ul>
<li>整体 script 代码</li>
<li><code>setTimeout</code></li>
<li><code>setInterval</code></li>
<li><code>I/O</code></li>
<li>UI 交互事件</li>
<li><code>postMessage</code></li>
<li><code>MessageChannel</code></li>
<li><code>setImmediate</code> Node.js 环境</li>
</ul>
<h2 id="微任务">微任务</h2>
<p>微任务（<em>microtask</em>）指在当前宏任务执行结束后，页面渲染前立即执行的任务。因此微任务的响应速度比 <code>setTimeout(() =&gt; {}, 0)</code> 更快，而且比渲染也快。</p>
<p>常见的微任务包括：</p>
<ul>
<li><code>Promise.then()</code></li>
<li><code>Object.observe</code></li>
<li><code>MutationObserver</code></li>
<li><code>process.nextTick</code> Node.js 环境</li>
</ul>
<h2 id="ref">REF</h2>
<ol>
<li><a href="https://zhuanlan.zhihu.com/p/78113300">js 中的宏任务与微任务</a> by <em>tigerHee</em>, 2021-09-30</li>
<li><a href="https://www.zhihu.com/zvideo/1425829930093043712">深入探究宏任务 &amp; 微任务的运行机制</a> by <em>对方正在长头发</em>, 2021-09-27。视频讲解宏任务和微任务</li>
<li><a href="https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/">Tasks, microtasks, queues and schedules</a>, by <em>Jake Archibald</em>, 2015-08-17</li>
<li><a href="https://www.bilibili.com/video/av413179257">What the heck is the event loop anyway?</a>, by <em>Philip Roberts</em>, JSConf EU 2014</li>
<li><a href="https://www.bilibili.com/video/BV1a4411F7t7">In the Loop</a>, by <em>Jake Archibald</em>, JSConf 2018</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver">MutationObserver</a>, MDN</li>
<li><a href="https://javascript.info/microtask-queue">Microtasks</a>, javascript.info</li>
<li><a href="https://javascript.info/event-loop">Event loop: microtasks and macrotasks</a>, javascript.info</li>
</ol>
<a href="https://gitee.com/liuz2/liuz2/blob/master/content/posts/task-and-microtask.md#tree_comm_title" class="no-underline db b--black pa2 tc bg-black-90" style="color:#eee;">进入留言</a><ul class="pa0">
  
   <li class="list dib">
     <a href="/tags/javascript" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">javascript</a>
   </li>
  
</ul>
<div class="mt6 instapaper_ignoref">
      
      
      </div>
    </div>

    <aside class="w-30-l mt6-l">




  <div class="bg-light-gray pa3 nested-list-reset nested-copy-line-height nested-links">
    <p class="f5 b mb3">相关內容</p>
    <ul class="pa0 list">
	   
	     <li  class="mb2">
          <a href="/posts/map-and-set/">Set 和 Map 的用法</a>
        </li>
	    
	     <li  class="mb2">
          <a href="/posts/javascript-variables/">Javascript 的变量、作用域和内存</a>
        </li>
	    
	     <li  class="mb2">
          <a href="/posts/string-replace-explained/">string.replace() 详解</a>
        </li>
	    
	     <li  class="mb2">
          <a href="/posts/change-event-of-input/">关于文本输入框 change 事件触发时机</a>
        </li>
	    
    </ul>
</div>

</aside>

  </article>

    </main>
    <footer class="bg-black bottom-0 w-100 pa3" role="contentinfo">
  <div class="flex justify-between">
  <a class="f4 fw4 hover-white no-underline white-70 dn dib-ns pv2 ph3" href="https://liuz2.gitee.io/" >
    &copy;  liuz2's Blog 2022 
  </a>
    <div>














</div>
  </div>
</footer>

    

  <script src="/dist/js/app.3fc0f988d21662902933.js"></script>


  </body>
</html>
